/*
* ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
* Without permission, no one has the right to obtain, disclose or use this software in any way.
*/

package ecarx.xsf.notificationcenter;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.service.notification.StatusBarNotification;
import android.util.Log;

import androidx.annotation.MainThread;

import ecarx.eas.notification.StatusBarTyrantNotification;

import ecarx.xsf.notificationcenter.notification.INotificationListener;


public class NotificationCenterData {

    private static final String TAG = "NotificationCenterData";

    private static NotificationCenterData centerData;

    private Handler mHandler;

    /**
     * 添加一条通知
     */
    private static final int ACTION_NOTIFICATION_ADD = 100;
    /**
     * 取消通知(如果取消全部的消息那么也是这里一条一条来的)
     */
    private static final int ACTION_NOTIFICATION_CANCEL_ONE = 101;

    private static final int ACTION_TYRANT_NOTIFICATION_ADD = 104;

    private static final int ACTION_TYRANT_NOTIFICATION_CANCEL = 105;

    /**
     * 远程回调给UI层数据的集合
     */
    private RemoteCallbackList<INotificationListener> mCallbackList;

    public static NotificationCenterData getInstance() {
        if (centerData == null) {
            synchronized (NotificationCenterData.class) {
                if (centerData == null) {
                    centerData = new NotificationCenterData();
                }
            }
        }
        return centerData;
    }

    private NotificationCenterData() {
        initDataDistributor();
    }

    /**
     * 初始化handler执行数据分发
     */
    private void initDataDistributor() {
        Log.i(TAG, "init Data Distributor");
        if (mHandler == null) {
            Looper currentLooper = Looper.myLooper();
            if (currentLooper == null) {
                HandlerThread handlerThread = new HandlerThread("NotificationCenterData");
                handlerThread.start();
                currentLooper = handlerThread.getLooper();
            }
            mHandler = new DispatcherHandler(currentLooper);
        }
    }


    /**
     * 远程View的代理回调
     *
     * @param callbackList 远程服务集合列表
     */
    public void setRemoteCallback(RemoteCallbackList<INotificationListener> callbackList) {
        mCallbackList = callbackList;
    }

    private class DispatcherHandler extends Handler {

        DispatcherHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            StatusBarNotification record;
            switch (msg.what) {
                case ACTION_NOTIFICATION_ADD:
                    record = (StatusBarNotification) msg.obj;
                    enqueueNotificationWithTagInternal(record);
                    break;
                case ACTION_NOTIFICATION_CANCEL_ONE:
                    record = (StatusBarNotification) msg.obj;
                    cancelNotificationWithTagInternal(record);
                    break;
                case ACTION_TYRANT_NOTIFICATION_ADD:
                    StatusBarTyrantNotification notification = (StatusBarTyrantNotification) msg.obj;
                    enqueueTyrantNotificationInternal(notification);
                    break;
                case ACTION_TYRANT_NOTIFICATION_CANCEL:
                    notification = (StatusBarTyrantNotification) msg.obj;
                    cancelTyrantNotificationInternal(notification);
                    break;
                default:
                    break;
            }
        }
    }

    @MainThread
    private void enqueueNotificationWithTagInternal(StatusBarNotification record) {
        postNotification(record);
    }

    @MainThread
    private void cancelNotificationWithTagInternal(StatusBarNotification record) {
        cancelNotification(record);
    }

    @MainThread
    private void enqueueTyrantNotificationInternal(StatusBarTyrantNotification notification) {
        postNotification(notification);
    }

    @MainThread
    private void cancelTyrantNotificationInternal(StatusBarTyrantNotification notification) {
        cancelNotification(notification);
    }

    private void postNotification(StatusBarNotification notificationRecord) {
        if (mCallbackList != null) {
            int N = mCallbackList.beginBroadcast();
            Log.i(TAG, "postNotificationToPanel with CallbackList.count= " + N);
            for (int i = 0; i < N; i++) {
                INotificationListener listener = mCallbackList.getBroadcastItem(i);
                try {
                    listener.onNotificationPosted(notificationRecord);
                } catch (RemoteException e) {
                    Log.e(TAG, "post remote exception " + e);
                }
            }
            mCallbackList.finishBroadcast();
        }
    }


    /**
     * 删除数据至NotificationPanelView
     *
     * @param notificationRecord 通知实体类
     */
    private void cancelNotification(StatusBarNotification notificationRecord) {
        if (mCallbackList == null) {
            return;
        }
        int N = mCallbackList.beginBroadcast();
        for (int i = 0; i < N; i++) {
            INotificationListener listener = mCallbackList.getBroadcastItem(i);
            try {
                listener.onNotificationRemoved(notificationRecord);
            } catch (RemoteException e) {
                Log.e(TAG, "cancel notification remote exception " + e);
            }
        }
        mCallbackList.finishBroadcast();
    }

    private void postNotification(StatusBarTyrantNotification notification) {
        if (mCallbackList != null) {
            int N = mCallbackList.beginBroadcast();
            Log.i(TAG, "postTyrantNotificationToPanel with CallbackList.count= " + N);
            for (int i = 0; i < N; i++) {
                INotificationListener listener = mCallbackList.getBroadcastItem(i);
                try {
                    listener.onTyrantNotificationPost(notification);
                } catch (RemoteException e) {
                    Log.e(TAG, "post remote exception " + e);
                }
            }
            mCallbackList.finishBroadcast();
        }
    }


    /**
     * 删除数据至NotificationPanelView
     **/
    private void cancelNotification(StatusBarTyrantNotification notification) {
        if (mCallbackList == null) {
            return;
        }
        int N = mCallbackList.beginBroadcast();
        for (int i = 0; i < N; i++) {
            INotificationListener listener = mCallbackList.getBroadcastItem(i);
            try {
                listener.onTyrantNotificationRemoved(notification);
            } catch (RemoteException e) {
                Log.e(TAG, "cancel notification remote exception " + e);
            }
        }
        mCallbackList.finishBroadcast();
    }


    /**
     * 加入一条新的通知
     */
    public void enqueueNotificationWithTag(StatusBarNotification record) {
        Log.i(TAG, "enqueueNotificationWithTag");
        Message message = Message.obtain();
        message.what = ACTION_NOTIFICATION_ADD;
        message.obj = record;
        mHandler.sendMessage(message);
    }

    public void enqueueTyrantNotification(StatusBarTyrantNotification notification) {
        Message msg = Message.obtain();
        msg.what = ACTION_TYRANT_NOTIFICATION_ADD;
        msg.obj = notification;
        mHandler.sendMessage(msg);
    }

    public void cancelTyrantNotification(StatusBarTyrantNotification notification) {
        Message msg = Message.obtain();
        msg.what = ACTION_TYRANT_NOTIFICATION_CANCEL;
        msg.obj = notification;
        mHandler.sendMessage(msg);
    }

    /**
     * 取消一条消息
     *
     * @param record 数据
     */
    public void cancelNotificationWithTag(StatusBarNotification record) {
        Message message = Message.obtain();
        message.what = ACTION_NOTIFICATION_CANCEL_ONE;
        message.obj = record;
        mHandler.sendMessage(message);
    }

}
